﻿using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace MyCoreLib.Automation.Data.SqlClient.Model
{
    using System;
    using System.Threading;
    using Metadata;

    public class SelectionInfo
    {        
        public readonly ReadOnlyCollection<ContractInfo> Contracts;

        public readonly ReadOnlyCollection<StoredProcedureInfo> StoredProcedures;


        public static SelectionInfo Create(
            IOutput output,
            ISelection selection)
        {
            if (ReferenceEquals(output, null))
            {
                throw new ArgumentNullException("output");
            }

            if (ReferenceEquals(selection, null))
            {
                throw new ArgumentNullException("selection");
            }

            var environmentSettingsReader = new EnvironmentSettingsReader(output);
            string connectionString = environmentSettingsReader.GetConnectionString(selection.DefaultConnectionString, selection.EnvironmentSettingsCollection);
            var schemaReader = new SqlSchemaReader2012(output, connectionString);
            return new SelectionInfo(
                output, 
                selection, 
                environmentSettingsReader,
                schemaReader,
                new ContractBinder());
        }

        public SelectionInfo(
            IOutput output,
            ISelection selection, 
            IEnvironmentSettingsReader environmentSettingsReader,
            ISqlSchemaReader schemaReader,
            IContractBinder contractBinder)
        {
            if (ReferenceEquals(output, null))
            {
                throw new ArgumentNullException("output");
            }

            if (ReferenceEquals(selection, null))
            {
                throw new ArgumentNullException("selection");
            }
            
            var schemaInfo = new DbSchemaInfo(schemaReader, CancellationToken.None);

            var contracts =
                from c in selection.Contracts ?? Enumerable.Empty<IContract>()
                where !ReferenceEquals(c, null)
                select new ContractInfo(output, c);

            Contracts = new ReadOnlyCollection<ContractInfo>(contracts.ToList());
            var ixContractByName = Contracts.ToDictionary(c => c.Name, StringComparer.OrdinalIgnoreCase);

            var selectedProcedures =
                from sp in selection.StoredProcedures
                select new StoredProcedureSelectorInfo(output, sp);

            var list = new List<StoredProcedureInfo>();
            StoredProcedures = new ReadOnlyCollection<StoredProcedureInfo>(list);

            foreach (var procedure in selectedProcedures)
            {                                
                if (schemaInfo.ProcedureExist(procedure))
                {
                    var xxx = new StoredProcedureInfo(output, procedure, ixContractByName);
                    list.Add(new StoredProcedureInfo(output, procedure, ixContractByName));
                }
                else
                {
                    output.Error("The {0} selected stored procedure is not found in the database.");
                }
            }

            bool exists = schemaInfo.ProcedureExist(new GenericDbObject("dbo", "usplogerror"));             
        }
        
    }
}
